home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / C / Applications / Python 1.3.3 / pbmplus / pbm / libpbm1.c < prev    next >
Text File  |  1995-06-14  |  14KB  |  739 lines

  1. /* libpbm1.c - pbm utility library part 1
  2. **
  3. ** Copyright (C) 1988 by Jef Poskanzer.
  4. **
  5. ** Permission to use, copy, modify, and distribute this software and its
  6. ** documentation for any purpose and without fee is hereby granted, provided
  7. ** that the above copyright notice appear in all copies and that both that
  8. ** copyright notice and this permission notice appear in supporting
  9. ** documentation.  This software is provided "as is" without express or
  10. ** implied warranty.
  11. **
  12. ** Modified by Jack Jansen, CWI, June 1994, to allow more flexible error
  13. ** control. The routines pm_setmsghandler and pm_setexithandler allow new
  14. ** handlers to be substituted for the default print resp. print-and-exit
  15. ** routines. The default msghandler prints the string arg to stderr, the
  16. ** default exithandler simply does an exit(1).
  17. */
  18.  
  19. #include "pbm.h"
  20. #include "version.h"
  21. #include "libpbm.h"
  22. #if __STDC__
  23. #include <stdarg.h>
  24. #else /*__STDC__*/
  25. #include <varargs.h>
  26. #endif /*__STDC__*/
  27.  
  28.     
  29.  
  30. /* Forward routines. */
  31.  
  32. #if defined(NEED_VFPRINTF1) || defined(NEED_VFPRINTF2)
  33. int vfprintf ARGS(( FILE* stream, char* format, va_list args ));
  34. #endif /*NEED_VFPRINTF*/
  35.  
  36. /* The new error handling code */
  37. static void
  38. pm_dftmsghandler(msg)
  39.     char *msg;
  40. {
  41.     fprintf(stderr, "%s", msg);
  42. }
  43.  
  44. static void
  45. pm_dftexithandler()
  46. {
  47.     exit(1);
  48. }
  49.  
  50. static void (*pm_curmsghandler)() = pm_dftmsghandler;
  51. static void (*pm_curexithandler)() = pm_dftexithandler;
  52.  
  53. void
  54. pm_setmsghandler(rtn)
  55.     void (*rtn)();
  56. {
  57.     if ( rtn == NULL )
  58.     rtn = pm_dftmsghandler;
  59.     pm_curmsghandler = rtn;
  60. }
  61.  
  62. void
  63. pm_setexithandler(rtn)
  64.     void (*rtn)();
  65. {
  66.     if ( rtn == NULL )
  67.     rtn = pm_dftexithandler;
  68.     pm_curexithandler = rtn;
  69. }
  70.  
  71.  
  72. /* Variable-sized arrays. */
  73.  
  74. char*
  75. pm_allocrow( cols, size )
  76.     int cols;
  77.     int size;
  78.     {
  79.     register char* itrow;
  80.  
  81.     itrow = (char*) malloc( cols * size );
  82.     if ( itrow == (char*) 0 )
  83.     pm_error( "out of memory allocating a row" );
  84.     return itrow;
  85.     }
  86.  
  87. void
  88. pm_freerow( itrow )
  89.     char* itrow;
  90.     {
  91.     free( itrow );
  92.     }
  93.  
  94.  
  95. char**
  96. pm_allocarray( cols, rows, size )
  97.     int cols, rows;
  98.     int size;
  99.     {
  100.     char** its;
  101.     int i;
  102.  
  103.     its = (char**) malloc( rows * sizeof(char*) );
  104.     if ( its == (char**) 0 )
  105.     pm_error( "out of memory allocating an array" );
  106.     its[0] = (char*) malloc( rows * cols * size );
  107.     if ( its[0] == (char*) 0 )
  108.     pm_error( "out of memory allocating an array" );
  109.     for ( i = 1; i < rows; ++i )
  110.     its[i] = &(its[0][i * cols * size]);
  111.     return its;
  112.     }
  113.  
  114. void
  115. pm_freearray( its, rows )
  116.     char** its;
  117.     int rows;
  118.     {
  119.     free( its[0] );
  120.     free( its );
  121.     }
  122.  
  123.  
  124. /* Case-insensitive keyword matcher. */
  125.  
  126. int
  127. pm_keymatch( str, keyword, minchars )
  128.     char* str;
  129.     char* keyword;
  130.     int minchars;
  131.     {
  132.     register int len;
  133.  
  134.     len = strlen( str );
  135.     if ( len < minchars )
  136.     return 0;
  137.     while ( --len >= 0 )
  138.     {
  139.     register char c1, c2;
  140.  
  141.     c1 = *str++;
  142.     c2 = *keyword++;
  143.     if ( c2 == '\0' )
  144.         return 0;
  145.     if ( isupper( c1 ) )
  146.         c1 = tolower( c1 );
  147.     if ( isupper( c2 ) )
  148.         c1 = tolower( c2 );
  149.     if ( c1 != c2 )
  150.         return 0;
  151.     }
  152.     return 1;
  153.     }
  154.  
  155.  
  156. /* Log base two hacks. */
  157.  
  158. int
  159. pm_maxvaltobits( maxval )
  160.     int maxval;
  161.     {
  162.     if ( maxval <= 1 )
  163.     return 1;
  164.     else if ( maxval <= 3 )
  165.     return 2;
  166.     else if ( maxval <= 7 )
  167.     return 3;
  168.     else if ( maxval <= 15 )
  169.     return 4;
  170.     else if ( maxval <= 31 )
  171.     return 5;
  172.     else if ( maxval <= 63 )
  173.     return 6;
  174.     else if ( maxval <= 127 )
  175.     return 7;
  176.     else if ( maxval <= 255 )
  177.     return 8;
  178.     else if ( maxval <= 511 )
  179.     return 9;
  180.     else if ( maxval <= 1023 )
  181.     return 10;
  182.     else if ( maxval <= 2047 )
  183.     return 11;
  184.     else if ( maxval <= 4095 )
  185.     return 12;
  186.     else if ( maxval <= 8191 )
  187.     return 13;
  188.     else if ( maxval <= 16383 )
  189.     return 14;
  190.     else if ( maxval <= 32767 )
  191.     return 15;
  192.     else if ( (long) maxval <= 65535L )
  193.     return 16;
  194.     else
  195.     pm_error( "maxval of %d is too large!", maxval );
  196.     }
  197.  
  198. int
  199. pm_bitstomaxval( bits )
  200.     int bits;
  201.     {
  202.     return ( 1 << bits ) - 1;
  203.     }
  204.  
  205.  
  206. /* Initialization. */
  207.  
  208. static char* progname;
  209. static int showmessages;
  210.  
  211. void
  212. pm_init( argcP, argv )
  213.     int* argcP;
  214.     char* argv[];
  215.     {
  216.     int argn, i;
  217.  
  218.     /* Extract program name. */
  219.     progname = rindex( argv[0], '/');
  220.     if ( progname == NULL )
  221.     progname = argv[0];
  222.     else
  223.     ++progname;
  224.  
  225.     /* Check for any global args. */
  226.     showmessages = 1;
  227.     for ( argn = 1; argn < *argcP; ++argn )
  228.     {
  229.     if ( pm_keymatch( argv[argn], "-quiet", 6 ) )
  230.         {
  231.         showmessages = 0;
  232.         }
  233.     else if ( pm_keymatch( argv[argn], "-version", 7 ) )
  234.         {
  235.         pm_message( "Version of %s", PBMPLUS_VERSION );
  236. #ifdef BSD
  237.         pm_message( "BSD defined" );
  238. #endif /*BSD*/
  239. #ifdef SYSV
  240.         pm_message( "SYSV defined" );
  241. #endif /*SYSV*/
  242. #ifdef MSDOS
  243.         pm_message( "MSDOS defined" );
  244. #endif /*MSDOS*/
  245. #ifdef PBMPLUS_RAWBITS
  246.         pm_message( "PBMPLUS_RAWBITS defined" );
  247. #endif /*PBMPLUS_RAWBITS*/
  248. #ifdef PBMPLUS_BROKENPUTC1
  249.         pm_message( "PBMPLUS_BROKENPUTC1 defined" );
  250. #endif /*PBMPLUS_BROKENPUTC1*/
  251. #ifdef PBMPLUS_BROKENPUTC2
  252.         pm_message( "PBMPLUS_BROKENPUTC2 defined" );
  253. #endif /*PBMPLUS_BROKENPUTC2*/
  254. #ifdef PGM_BIGGRAYS
  255.         pm_message( "PGM_BIGGRAYS defined" );
  256. #endif /*PGM_BIGGRAYS*/
  257. #ifdef PPM_PACKCOLORS
  258.         pm_message( "PPM_PACKCOLORS defined" );
  259. #endif /*PPM_PACKCOLORS*/
  260. #ifdef DEBUG
  261.         pm_message( "DEBUG defined" );
  262. #endif /*DEBUG*/
  263. #ifdef NEED_VFPRINTF1
  264.         pm_message( "NEED_VFPRINTF1 defined" );
  265. #endif /*NEED_VFPRINTF1*/
  266. #ifdef NEED_VFPRINTF2
  267.         pm_message( "NEED_VFPRINTF2 defined" );
  268. #endif /*NEED_VFPRINTF2*/
  269. #ifdef RGB_DB
  270.         pm_message( "RGB_DB=\"%s\"", RGB_DB );
  271. #endif /*RGB_DB*/
  272. #ifdef LIBTIFF
  273.         pm_message( "LIBTIFF defined" );
  274. #endif /*LIBTIFF*/
  275.         pm_curexithandler();
  276.         }
  277.     else
  278.         continue;
  279.     for ( i = argn + 1; i <= *argcP; ++i )
  280.         argv[i - 1] = argv[i];
  281.     --(*argcP);
  282.     }
  283.     }
  284.  
  285. void
  286. pbm_init( argcP, argv )
  287.     int* argcP;
  288.     char* argv[];
  289.     {
  290.     pm_init( argcP, argv );
  291.     }
  292.  
  293.  
  294. /* Error handling. */
  295.  
  296. void
  297. pm_usage( usage )
  298.     char* usage;
  299.     {
  300.     char buf[1000];
  301.  
  302.     sprintf( buf, "usage:  %s %s\n", progname, usage );
  303.     pm_curmsghandler(buf);
  304.     pm_curexithandler();
  305.     }
  306.  
  307. #ifndef __MWERKS__
  308. void
  309. pm_perror( reason )
  310.     char* reason;
  311.     {
  312.     extern char* sys_errlist[];
  313.     extern int errno;
  314.     char* e;
  315.  
  316.     e = sys_errlist[errno];
  317.  
  318.     if ( reason != 0 && reason[0] != '\0' )
  319.     pm_error( "%s - %s", reason, e );
  320.     else
  321.     pm_error( "%s", e );
  322.     }
  323. #endif
  324.  
  325. #if __STDC__
  326. void
  327. pm_message( char* format, ... )
  328.     {
  329.     va_list args;
  330.  
  331.     va_start( args, format );
  332. #else /*__STDC__*/
  333. /*VARARGS1*/
  334. void
  335. pm_message( va_alist )
  336.     va_dcl
  337.     { /*}*/
  338.     va_list args;
  339.     char* format;
  340.  
  341.     va_start( args );
  342.     format = va_arg( args, char* );
  343. #endif /*__STDC__*/
  344.  
  345.     if ( showmessages )
  346.     {
  347.     char buf[1000], *bufp;
  348.     sprintf( buf, "%s: ", progname ); bufp = buf+strlen(buf);
  349.     (void) vsprintf( bufp, format, args );
  350.     strcat(buf, "\n");
  351.     pm_curmsghandler(buf);
  352.     }
  353.     va_end( args );
  354.     }
  355.  
  356. #if __STDC__
  357. void
  358. pm_error( char* format, ... )
  359.     {
  360.     va_list args;
  361.  
  362.     va_start( args, format );
  363. #else /*__STDC__*/
  364. /*VARARGS1*/
  365. void
  366. pm_error( va_alist )
  367.     va_dcl
  368.     { /*}*/
  369.     va_list args;
  370.     char* format;
  371.  
  372.     va_start( args );
  373.     format = va_arg( args, char* );
  374. #endif /*__STDC__*/
  375.  
  376.     {
  377.     char buffer[1000], *bufp;
  378.     
  379.     sprintf( buffer, "%s: ", progname ); bufp = buffer+strlen(buffer);
  380.     (void) vsprintf( bufp, format, args );
  381.     strcat(buffer, "\n");
  382.     pm_curmsghandler(buffer);
  383.     }
  384.     va_end( args );
  385.     pm_curexithandler();
  386.     }
  387.  
  388. #ifdef NEED_VFPRINTF1
  389.  
  390. /* Micro-vfprintf, for systems that don't have vfprintf but do have _doprnt.
  391. */
  392.  
  393. int
  394. vfprintf( stream, format, args )
  395.     FILE* stream;
  396.     char* format;
  397.     va_list args;
  398.     {
  399.     return _doprnt( format, args, stream );
  400.     }
  401. Sorry, you will have to write a vsprintf yourself;
  402.     
  403. #endif /*NEED_VFPRINTF1*/
  404.  
  405. #ifdef NEED_VFPRINTF2
  406.  
  407. /* Portable mini-vfprintf, for systems that don't have either vfprintf or
  408. ** _doprnt.  This depends only on fprintf.  If you don't have fprintf,
  409. ** you might consider getting a new stdio library.
  410. */
  411.  
  412. int
  413. vsprintf( stream, format, args )
  414.     char* stream;
  415.     char* format;
  416.     va_list args;
  417.     {
  418.     int n;
  419.     char* ep;
  420.     char fchar;
  421.     char tformat[512];
  422.     int do_long;
  423.     int i;
  424.     long l;
  425.     unsigned u;
  426.     unsigned long ul;
  427.     char* s;
  428.     double d;
  429.  
  430.     n = 0;
  431.     while ( *format != '\0' )
  432.     {
  433.     if ( *format != '%' )
  434.         { /* Not special, just write out the char. */
  435.         *stream++ = format;
  436.         ++n;
  437.         ++format;
  438.         }
  439.     else
  440.         {
  441.         do_long = 0;
  442.         ep = format + 1;
  443.  
  444.         /* Skip over all the field width and precision junk. */
  445.         if ( *ep == '-' )
  446.         ++ep;
  447.         if ( *ep == '0' )
  448.         ++ep;
  449.         while ( isdigit( *ep ) )
  450.         ++ep;
  451.         if ( *ep == '.' )
  452.         {
  453.         ++ep;
  454.         while ( isdigit( *ep ) )
  455.             ++ep;
  456.         }
  457.         if ( *ep == '#' )
  458.         ++ep;
  459.         if ( *ep == 'l' )
  460.         {
  461.         do_long = 1;
  462.         ++ep;
  463.         }
  464.  
  465.         /* Here's the field type.  Extract it, and copy this format
  466.         ** specifier to a temp string so we can add an end-of-string.
  467.         */
  468.         fchar = *ep;
  469.         (void) strncpy( tformat, format, ep - format + 1 );
  470.         tformat[ep - format + 1] = '\0';
  471.  
  472.         /* Now do a one-argument fprintf with the format string we have
  473.         ** isolated.
  474.         */
  475.         switch ( fchar )
  476.         {
  477.         case 'd':
  478.         if ( do_long )
  479.             {
  480.             l = va_arg( args, long );
  481.             n += sprintf( stream, tformat, l );
  482.              stream += strlen(stream);
  483.             }
  484.         else
  485.             {
  486.             i = va_arg( args, int );
  487.             n += sprintf( stream, tformat, i );
  488.              stream += strlen(stream);
  489.             }
  490.         break;
  491.  
  492.             case 'o':
  493.             case 'x':
  494.             case 'X':
  495.             case 'u':
  496.         if ( do_long )
  497.             {
  498.             ul = va_arg( args, unsigned long );
  499.             n += sprintf( stream, tformat, ul );
  500.              stream += strlen(stream);
  501.             }
  502.         else
  503.             {
  504.             u = va_arg( args, unsigned );
  505.             n += sprintf( stream, tformat, u );
  506.             stream += strlen(stream);
  507.             }
  508.         break;
  509.  
  510.             case 'c':
  511.         i = (char) va_arg( args, int );
  512.         n += sprintf( stream, tformat, i ); stream += strlen(stream);
  513.         break;
  514.  
  515.             case 's':
  516.         s = va_arg( args, char* );
  517.         n += sprintf( stream, tformat, s ); stream += strlen(stream);
  518.         break;
  519.  
  520.             case 'e':
  521.             case 'E':
  522.             case 'f':
  523.             case 'g':
  524.             case 'G':
  525.         d = va_arg( args, double );
  526.         n += sprintf( stream, tformat, d ); stream += strlen(stream);
  527.         break;
  528.  
  529.             case '%':
  530.         *stream++ = '%';
  531.         ++n;
  532.         break;
  533.  
  534.         default:
  535.         return -1;
  536.         }
  537.  
  538.         /* Resume formatting on the next character. */
  539.         format = ep + 1;
  540.         }
  541.     }
  542.     *stream = '\0';
  543.     return nc;
  544.     }
  545. #endif /*NEED_VFPRINTF2*/
  546.  
  547. #ifndef __MWERKS__
  548. /* File open/close that handles "-" as stdin and checks errors. */
  549.  
  550. FILE*
  551. pm_openr( name )
  552.     char* name;
  553.     {
  554.     FILE* f;
  555.  
  556.     if ( strcmp( name, "-" ) == 0 )
  557.     f = stdin;
  558.     else
  559.     {
  560. #ifdef MSDOS
  561.     f = fopen( name, "rb" );
  562. #else /*MSDOS*/
  563.     f = fopen( name, "r" );
  564. #endif /*MSDOS*/
  565.     if ( f == NULL )
  566.         {
  567.         pm_perror( name );
  568.         pm_curexithandler();
  569.         }
  570.     }
  571.     return f;
  572.     }
  573.  
  574. FILE*
  575. pm_openw( name )
  576.     char* name;
  577.     {
  578.     FILE* f;
  579.  
  580. #ifdef MSDOS
  581.     f = fopen( name, "wb" );
  582. #else /*MSDOS*/
  583.     f = fopen( name, "w" );
  584. #endif /*MSDOS*/
  585.     if ( f == NULL )
  586.     {
  587.     pm_perror( name );
  588.     pm_curexithandler();
  589.     }
  590.     return f;
  591.     }
  592.  
  593. void
  594. pm_close( f )
  595.     FILE* f;
  596.     {
  597. #ifdef POSIX
  598.     fflush( f );
  599. #endif
  600.     if ( ferror( f ) )
  601.     pm_message( "a file read or write error occurred at some point" );
  602.     if ( f != stdin )
  603.     if ( fclose( f ) != 0 )
  604.         pm_perror( "fclose" );
  605.     }
  606. #endif /* not __MWERKS__ */
  607. /* Endian I/O.
  608. */
  609.  
  610. int
  611. pm_readbigshort( in, sP )
  612.     FILE* in;
  613.     short* sP;
  614.     {
  615.     int c;
  616.  
  617.     if ( (c = getc( in )) == EOF )
  618.     return -1;
  619.     *sP = ( c & 0xff ) << 8;
  620.     if ( (c = getc( in )) == EOF )
  621.     return -1;
  622.     *sP |= c & 0xff;
  623.     return 0;
  624.     }
  625.  
  626. #if __STDC__
  627. int
  628. pm_writebigshort( FILE* out, short s )
  629. #else /*__STDC__*/
  630. int
  631. pm_writebigshort( out, s )
  632.     FILE* out;
  633.     short s;
  634. #endif /*__STDC__*/
  635.     {
  636.     (void) putc( ( s >> 8 ) & 0xff, out );
  637.     (void) putc( s & 0xff, out );
  638.     return 0;
  639.     }
  640.  
  641. int
  642. pm_readbiglong( in, lP )
  643.     FILE* in;
  644.     long* lP;
  645.     {
  646.     int c;
  647.  
  648.     if ( (c = getc( in )) == EOF )
  649.     return -1;
  650.     *lP = ( c & 0xff ) << 24;
  651.     if ( (c = getc( in )) == EOF )
  652.     return -1;
  653.     *lP |= ( c & 0xff ) << 16;
  654.     if ( (c = getc( in )) == EOF )
  655.     return -1;
  656.     *lP |= ( c & 0xff ) << 8;
  657.     if ( (c = getc( in )) == EOF )
  658.     return -1;
  659.     *lP |= c & 0xff;
  660.     return 0;
  661.     }
  662.  
  663. int
  664. pm_writebiglong( out, l )
  665.     FILE* out;
  666.     long l;
  667.     {
  668.     (void) putc( ( l >> 24 ) & 0xff, out );
  669.     (void) putc( ( l >> 16 ) & 0xff, out );
  670.     (void) putc( ( l >> 8 ) & 0xff, out );
  671.     (void) putc( l & 0xff, out );
  672.     return 0;
  673.     }
  674.  
  675. int
  676. pm_readlittleshort( in, sP )
  677.     FILE* in;
  678.     short* sP;
  679.     {
  680.     int c;
  681.  
  682.     if ( (c = getc( in )) == EOF )
  683.     return -1;
  684.     *sP = c & 0xff;
  685.     if ( (c = getc( in )) == EOF )
  686.     return -1;
  687.     *sP |= ( c & 0xff ) << 8;
  688.     return 0;
  689.     }
  690.  
  691. #if __STDC__
  692. int
  693. pm_writelittleshort( FILE* out, short s )
  694. #else /*__STDC__*/
  695. int
  696. pm_writelittleshort( out, s )
  697.     FILE* out;
  698.     short s;
  699. #endif /*__STDC__*/
  700.     {
  701.     (void) putc( s & 0xff, out );
  702.     (void) putc( ( s >> 8 ) & 0xff, out );
  703.     return 0;
  704.     }
  705.  
  706. int
  707. pm_readlittlelong( in, lP )
  708.     FILE* in;
  709.     long* lP;
  710.     {
  711.     int c;
  712.  
  713.     if ( (c = getc( in )) == EOF )
  714.     return -1;
  715.     *lP = c & 0xff;
  716.     if ( (c = getc( in )) == EOF )
  717.     return -1;
  718.     *lP |= ( c & 0xff ) << 8;
  719.     if ( (c = getc( in )) == EOF )
  720.     return -1;
  721.     *lP |= ( c & 0xff ) << 16;
  722.     if ( (c = getc( in )) == EOF )
  723.     return -1;
  724.     *lP |= ( c & 0xff ) << 24;
  725.     return 0;
  726.     }
  727.  
  728. int
  729. pm_writelittlelong( out, l )
  730.     FILE* out;
  731.     long l;
  732.     {
  733.     (void) putc( l & 0xff, out );
  734.     (void) putc( ( l >> 8 ) & 0xff, out );
  735.     (void) putc( ( l >> 16 ) & 0xff, out );
  736.     (void) putc( ( l >> 24 ) & 0xff, out );
  737.     return 0;
  738.     }
  739.